/**
 *    Copyright (C) 2008, 2009  Victor Smirnov <aist11@gmail.com>
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License along
 *    with this program; if not, write to the Free Software Foundation, Inc.,
 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *    See LICENSE.exceptions in the root folder of this project for possible
 *    exceptions
 *
 */

#ifndef _CUBEFS_API_REFLECTION_ID_HPP
#define	_CUBEFS_API_REFLECTION_ID_HPP


#include <cubefs/api/types.hpp>
#include <cubefs/api/reflection/value.hpp>


namespace cubefs    {
namespace api       {

class CUBEFS_API IDValue {
    Byte data_[8];
public:
    IDValue() {
        clear();
    }

    template <typename T>
    IDValue(const T* id) {
        clear();
        id->CopyTo(ptr());
    }

    IDValue(StringRef id) {
    	clear();

    }

    void clear() {
        for (Int c = 0; c < sizeof(data_); c++) {
            data_[c] = 0;
        }
    }

    template <typename T>
    void set(const T& id) {
        clear();
        id.CopyTo(ptr());
    }

    template <typename T>
    const T get() const {
        return T(*this);
    }

    const void* ptr() const {
        return data_;
    }

    void* ptr() {
        return data_;
    }

    const char* cptr() const {
        return data_;
    }

    virtual const String str() const {
        char text[sizeof(data_)*2 + 3];
        text[0] = '0';
        text[1] = 'x';
        text[sizeof(text) - 1] = 0;

        for (Int c = 0; c < sizeof(data_); c++) {
            text[c*2 + 3] = get_char(data_[sizeof(data_) - c - 1] & 0xf);
            text[c*2 + 2] = get_char((data_[sizeof(data_) - c - 1] >> 4) & 0xf);
        }

        return String(text);
    }

    virtual bool IsNull() const {
        for (Int c = 0; c < sizeof(data_); c++) {
            if (data_[c] != 0) {
                return false;
            }
        }
        return true;
    }

    bool equals(const IDValue& other) const {
        for (Int c = 0; c < sizeof(data_); c++) {
            if (data_[c] != other.data_[c]) {
                return false;
            }
        }
        return true;
    }

    bool operator==(const IDValue& other) const {
    	return equals(other);
    }

private:
    static char get_char(Byte value) {
        switch (value) {
            case 0: return '0';
            case 1: return '1';
            case 2: return '2';
            case 3: return '3';
            case 4: return '4';
            case 5: return '5';
            case 6: return '6';
            case 7: return '7';
            case 8: return '8';
            case 9: return '9';
            case 10: return 'a';
            case 11: return 'b';
            case 12: return 'c';
            case 13: return 'd';
            case 14: return 'e';
            case 15: return 'f';
        }
    }
};

typedef TypedValue<IDValue> TypedIDValue;

CUBEFS_DECLARE_TYPENAME(IDValue, 	"cubefs::api::IDValue");
CUBEFS_DEFINE_TYPE_HASH(IDValue,    120);

}
}

namespace std {

ostream& operator<<(ostream& os, const cubefs::api::IDValue& id);

}
#endif

